﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MySql.Data;
using MySql.Data.MySqlClient;
using Contacts.Mail;
using System.Windows.Forms.ComponentModel;
#if!__MonoCS__
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop.Outlook;
#endif
using System.Security.Principal;
using System.Configuration;
using System.Threading;
using Workbench.Properties;


namespace Contacts
{
	public partial class Contacts : Form
	{
		#region Private Declarations

		/// <summary>
		/// Holds the data from the MySql server
		/// </summary>
		DataSet contacts;
		ContactsAddEdit contf;
		ContactMessage mess;
		MySqlConn connect;
		BindingNavigator contactsbn = new BindingNavigator (true);
		BindingSource contactsbs = new BindingSource ();
		BindingSource grvbs = new BindingSource ();
		BindingSource project_contactsbs = new BindingSource ();
		DataColumn projectsdc = new DataColumn ();
		DataView pcview;
		DataRow original;
		DataRow current;
		DataTable user;
		DataTable currentpc = new DataTable ();
		DataRow pc;
		// olconn olc = new olconn();
		DataGridViewRow cr;
		public DataGridView datagrv;
		BackgroundWorker backgw;
		BackgroundWorker worker;
		DataView view;
		private int pi;
		private int rc;
		private int pcid;
		private int strid;
		private int lpcid;
		private int rowinEdit = -1;
		private bool a;
		private bool m;
		private bool d;
		string tostr;
		string ccstr;
		string bcstr;
		int id;
		string db;
		private int jrid;
		private int cid;
		bool verified = false;
		ComboBox combo;
		ProjectTypes ProjectType;
		StoreProgramTypes programtype;
		protected Microsoft.Exchange.WebServices.Authentication.TraceListener tracer;
		protected const string traceout = "ContactsTrace";

		#endregion

		#region Ctor
		public Contacts (MySqlConn Connection)
		{
			InitializeComponent ();
			this.ClientSize = Settings.Default.FORM_SIZE;
			tbo_time.Text = TimeofPull;
			datagrv = grd_jr_cont;
		}
		
		/// <summary>
		/// Initializes a new instance of the <see cref="Contacts.Contacts"/> class.
		/// </summary>
		/// <param name='projtype'>
		/// Projtype.
		/// </param>
		/// <param name='wmdata'>
		/// Wmdata.
		/// </param>
		public Contacts (Workbench.Bench.MainContactData ContactData) :
			this (ContactData.ProjectType, ContactData.JobToLoad, ContactData.DataToLoad)
		{
			/*if ((projtype & ProjectTypes.Remodel) == ProjectTypes.Remodel)
				ProjectType = ProjectTypes.Remodel;
			if ((projtype & ProjectTypes.GroundUp) == ProjectTypes.GroundUp)
				ProjectType = ProjectTypes.GroundUp; */
			ProjectType = ContactData.ProjectType;
			InitializeComponent ();
			this.ClientSize = Settings.Default.FORM_SIZE;
			tbo_time.Text = TimeofPull;
			SaveButton.Enabled = false;
			datagrv = grd_jr_cont;
		}
		
		/// <summary>
		/// Initializes a new instance of the <see cref="Contacts.Contacts"/> class.
		/// </summary>
		/// <param name='database'>
		/// Database.
		/// </param>
		public  Contacts (ProjectTypes projtype, JobFilter jobs, string database)
		{
			tracer = new Microsoft.Exchange.WebServices.Authentication.TraceListener();
			tracer.Trace(traceout, "\r\n");
			tracer.Trace(traceout, "Contacts Initialized");
			programtype = func.GetStoreProgramType (projtype);
			try {
				connect = new MySqlConn ( );tracer.Trace(traceout, "Mysql Connected");
				connect.Connect (database);
				
				connect.LoadWMdatabase (database, projtype, programtype, jobs);
				
				//connect.Connect ("contacts");
				
				connect.LoadContacts ();
				
				connect.Relations (programtype);
				
				connect.Disconnect ();tracer.Trace(traceout, "Mysql Connection Closed");
				
				contacts = connect.Data;
				
				TimeofPull = DateTime.Now.ToString ("d-MMM-yyyy HH:mm:ss");tracer.Trace(traceout, string.Format("\tData pull complete: {0}",TimeofPull));
				//tbo_time.Visible = false;
				
				GC.KeepAlive (connect);
			} catch (MySqlException ex) {
				string subject = "contacts data load error";
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}
		#endregion

		#region Public Properties
		public  string TimeofPull { get; private set; }

		public int Position { get; private set; }
		
		public BindingSource contactbs { get; set; }
		#endregion
		
		/// <summary>
		/// Makes the connection to the MySql database specified in the config file.
		/// Then loads the data and builds relations between everything.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		//public void Contacts_Load(object sender, EventArgs e)
		public void Contacts_Load (object sender, EventArgs e)
		{
			// begin loading the data
			
			tracer.Trace(traceout, "Form Load event");
			// end loading data
			datagrv = grd_jr_cont;

			
			// add additional columns
			DataColumn projsel = contacts.Tables [programtype.ToString()].Columns.Add ("str_sel");tracer.Trace(traceout, string.Format("\tAdd Data Column: {0}, {1}",projsel.Table.TableName,projsel.ColumnName));
			DataColumn fullname = contacts.Tables ["contacts"].Columns.Add ("full_name");tracer.Trace(traceout, string.Format("\tAdd Data Column: {0}, {1}",fullname.Table.TableName,projsel.ColumnName));
			DataColumn jrname = contacts.Tables ["project_contacts"].Columns.Add ("jr_name");tracer.Trace(traceout, string.Format("\tAdd Data Column: {0}, {1}",jrname.Table.TableName,projsel.ColumnName));
			DataColumn cntname = contacts.Tables ["project_contacts"].Columns.Add ("full_name");tracer.Trace(traceout, string.Format("\tAdd Data Column: {0}, {1}",cntname.Table.TableName,projsel.ColumnName));
			DataColumn compsel = contacts.Tables ["companies"].Columns.Add ("comp_sel");tracer.Trace(traceout, string.Format("\tAdd Data Column: {0}, {1}",compsel.Table.TableName,projsel.ColumnName));
			// end column add

			
			FormatContactNames ();
			
			FormatStoreNames ();
			
			FormatSelectorNames ();
			


			

			//this creates a company name by location for selector in the contacts form
			int m;
			int mrc = contacts.Tables ["companies"].Rows.Count;
			for (m = 0; m < mrc; m++) {
				DataRow comprow = contacts.Tables ["companies"].Rows [m];
				comprow ["comp_sel"] = comprow ["company_name"] + ", " + comprow ["street"] + ", " + comprow ["city"] + ", " + comprow ["state"];
			}
			
			contacts.AcceptChanges ();
			//this establishes the contacts sort, valuemember, displaymember, and binds it
			contacts.Tables ["contacts"].DefaultView.Sort = "full_name";
			contactsbs.DataSource = contacts;
			contactsbn.BindingSource = contactsbs;

			
			switch (programtype) {
				case StoreProgramTypes.WalMartRealty:
					{
						cbo_projects.ValueMember = "WalMartRealty.str_id";
						cbo_projects.DisplayMember = "WalMartRealty.str_sel";
						cbo_projects.DataSource = contactsbs;
					}
					break;
				case StoreProgramTypes.StoreLayout:
					{
						cbo_projects.ValueMember = "projects_remodels.str_id";
						cbo_projects.DisplayMember = "projects_remodels.str_sel";
						cbo_projects.DataSource = contactsbs;
					}
					break;
			}
			
			//this hides the 7 id's that make the datagridview work
            
            grd_jr_cont.Columns["project_contact_id"].Visible = false;
            grd_jr_cont.Columns["str_id"].Visible = false;
            grd_jr_cont.Columns["job_role_id"].Visible = false;
            grd_jr_cont.Columns["contact_id"].Visible = false;
            grd_jr_cont.Columns["jr_name"].Visible = false;
            grd_jr_cont.Columns["full_name"].Visible = false;
            grd_jr_cont.Columns["timestamp"].Visible = false;
            grd_jr_cont.Columns["user"].Visible = false;
			
			
			lpcid = (int)contacts.Tables ["project_contacts"].Rows [(contacts.Tables ["project_contacts"].Rows.Count - 1)] ["project_contact_id"];
			_isdirty = contacts.HasChanges ();
			if (_isdirty) SaveButton.Enabled = true;
			
		}

		/// <summary>
		/// Formats the store names. this creates a store select so projects will be shown alphabetized by city name in project selector or if the preferences allow, these are sorted by store number
		/// </summary>
		private void FormatStoreNames ()
		{tracer.Trace(traceout, "Formatting Store Names");
			int irc = contacts.Tables [programtype.ToString()].Rows.Count;tracer.Trace(traceout, string.Format("\tIterating over {0} records", irc));
			DataTable projects = contacts.Tables [programtype.ToString()]; if (projects == null ) throw new System.Exception();tracer.Trace(traceout, string.Format("\tReading from DataTable {0}", projects.TableName));
			for (int i = irc - 1; i >= 0; i--) {
				DataRow row = projects.Rows [i];

				switch (Workbench.Properties.Settings.Default.STORE_SORT) {
					case "STORE":
				    row ["str_sel"] = row ["str_num"].ToString () + '-' + row ["str_seq"] + ' ' + row ["str_city"].ToString () + ' ' + row ["str_st"].ToString ();
						continue;

					default:
						row ["str_sel"] = row ["str_city"].ToString () + ' ' + row ["str_st"].ToString () + ' ' + row ["str_num"] + '-' + row ["str_seq"];
						continue;
				}
			}tracer.Trace(traceout, "\t\tDone reading rows");
		}
		
		/// <summary>
		/// this creates a job role name and fullname so all records will be alphabetized by job role name then by fullname in datagridview
		/// </summary>
		private void FormatContactNames ()
		{tracer.Trace(traceout, "Formatting Contact Names");
		  int RowCount = contacts.Tables ["project_contacts"].Rows.Count;tracer.Trace(traceout, string.Format("\tIterating over {0} records", RowCount));
			for (int i = 0; i < RowCount; i++) {
				int JobRoleId = (int)contacts.Tables ["project_contacts"].Rows [i] ["job_role_id"];
				int ContactId = (int)contacts.Tables ["project_contacts"].Rows [i] ["contact_id"];
				DataRow JobRole = contacts.Tables ["job_roles"].Rows.Find (JobRoleId);
				DataRow Contact = contacts.Tables ["contacts"].Rows.Find (ContactId);
				DataRow Project = contacts.Tables ["project_contacts"].Rows [i];
				Project ["jr_name"] = JobRole ["job_role"].ToString ();
				string MiddleName = Contact ["middle_name"].ToString ();
				string name = null;
				if (String.IsNullOrEmpty (MiddleName)) {
					name = Contact ["first_name"].ToString () + " " + Contact ["last_name"].ToString ();
				} else {
					name = Contact ["first_name"].ToString () + " " + Contact ["middle_name"].ToString () + " " + Contact ["last_name"].ToString ();
				}
				
			}tracer.Trace(traceout, "\t\tDone reading rows");
		}
		
		/// <summary>
		/// this creates a full name select so contacts will be shown alphabetized by first/last name in contact selector
		/// or if preferences are set Last Name, First Name
		/// </summary>
		private void FormatSelectorNames ()
		{tracer.Trace(traceout, "Formatting Contact Selector Names");
			int RowCount = contacts.Tables ["contacts"].Rows.Count;tracer.Trace(traceout, string.Format("\tIterating over {0} records", RowCount));
			for (int i = 0; i < RowCount; i++) {
				DataRow Contact = contacts.Tables ["contacts"].Rows [i];
				string MiddleName = Contact ["middle_name"].ToString ();
				switch (Workbench.Properties.Settings.Default.DISPLAY_NAME_ORDER) {
					case "LAST":
						if (String.IsNullOrEmpty (MiddleName))
							Contact ["full_name"] = Contact ["last_name"].ToString () + ", " + Contact ["first_name"].ToString ();
						else
							Contact ["full_name"] = Contact ["last_name"].ToString () + ", " + Contact ["first_name"].ToString () + ' ' + Contact ["middle_name"].ToString ();
						break;

					default:
						if (String.IsNullOrEmpty (MiddleName))
							Contact ["full_name"] = Contact ["first_name"].ToString () + ' ' + Contact ["last_name"];
						else
							Contact ["full_name"] = Contact ["first_name"].ToString () + ' ' + Contact ["middle_name"].ToString () + ' ' + Contact ["last_name"];
						break;
				}
			}tracer.Trace(traceout, "\t\tDone reading rows");
		}
		
		//this allows the change in the project selector and re-fills the datagridview
		private void cbo_projects_SelectedIndexChanged (object sender, EventArgs e)
		{
			try {tracer.Trace(traceout, "project selector Combo box index changed event");
				pi = cbo_projects.SelectedIndex;
				pcview = new DataView (contacts.Tables ["project_contacts"]);
				pcview.RowFilter = string.Format (
					"str_id = {0}",
					cbo_projects.SelectedValue
				);tracer.Trace(traceout, string.Format("\tRow Filter: {0}",pcview.RowFilter));
				pcview.Sort = "jr_name, full_name";
				grd_jr_cont.DataSource = pcview;
				tbo_str_num.Text = contacts.Tables [programtype.ToString()].Rows [pi] ["str_num"].ToString ();
				tbo_str_num.BackColor = Color.Aquamarine;
				tbo_str_seq.Text = contacts.Tables [programtype.ToString()].Rows [pi] ["str_seq"].ToString ();
				tbo_str_seq.BackColor = Color.Aquamarine;
				tbo_str_city.Text = contacts.Tables [programtype.ToString()].Rows [pi] ["str_city"].ToString ();
				tbo_str_city.BackColor = Color.Aquamarine;
				tbo_str_st.Text = contacts.Tables [programtype.ToString()].Rows [pi] ["str_st"].ToString ();
				tbo_str_st.BackColor = Color.Aquamarine;
				cbo_job_roles.DataSource = contacts.Tables ["job_roles"];
				cbo_job_roles.ValueMember = "job_role_id";
				cbo_job_roles.DisplayMember = "job_role";
				cbo_contacts.DataSource = contacts.Tables ["contacts"];
				cbo_contacts.ValueMember = "contact_id";
				cbo_contacts.DisplayMember = "full_name";
				func.FillRows (contacts, grd_jr_cont, pb2, lab_save);
				grd_jr_cont.EndEdit ();
				int nr = grd_jr_cont.NewRowIndex;
				grd_jr_cont.CurrentCell = grd_jr_cont.Rows [nr].Cells [0];
				grd_jr_cont.CurrentCell.Style.BackColor = grd_jr_cont.DefaultCellStyle.BackColor;
				grd_jr_cont.EditMode = DataGridViewEditMode.EditOnEnter;
			} catch (System.Exception ex) {
				string subject = "cbo_projects_SelectedIndexChanged error";tracer.Trace(traceout, string.Format("\tComboBox Error: {0}",ex.Message));
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}

		//both the job role combo box and the contacts combo box are
		//cast into a combo box to do a selectindexchanged event
		
		private void grd_jr_cont_EditingControlShowing (object sender, DataGridViewEditingControlShowingEventArgs e)
		{
			try {
				combo = e.Control as ComboBox;

				combo.AutoCompleteSource = AutoCompleteSource.ListItems;
				combo.AutoCompleteMode = AutoCompleteMode.SuggestAppend;

				if (combo != null) {
					combo.SelectionChangeCommitted -= new EventHandler (combo_SelectionChangeCommitted); //this was combo.SelectionChangeCommitted -= new EventHandler(ComboBox_SelectedIndexChange)
					combo.SelectionChangeCommitted += new EventHandler (combo_SelectionChangeCommitted);
				}
			} catch (System.Exception ex) {
				string subject = "grd_jr_cont_EditingControlShowing error";
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}

		private void grd_jr_cont_RowHeaderMouseClick (object sender, EventArgs e)
		{
			grd_jr_cont.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
		}
		
		//this redefines the datagridview when either a change is made to the job role or contact
		private void combo_SelectionChangeCommitted (object sender, EventArgs e)  //this was ComboBox_SelectionChangeCommitted
		{
		  int cpcid = (int)grd_jr_cont.CurrentRow.Cells ["project_contact_id"].Value;tracer.Trace(traceout, string.Format("Grid edit row: {0}",cpcid.ToString()));
          SaveButton.Enabled = true;
			try {
				int ci = grd_jr_cont.CurrentCell.ColumnIndex;
				int cr = grd_jr_cont.NewRowIndex;
				string colname = grd_jr_cont.Columns [ci].HeaderText;tracer.Trace(traceout, string.Format("\tGrid Column: {0}",colname));
				int si = ((ComboBox)sender).SelectedIndex;
				bool jrnb = String.IsNullOrEmpty (grd_jr_cont.CurrentRow.Cells [0].FormattedValue.ToString ());tracer.Trace(traceout, string.Format("\t\tjrnb: {0}",jrnb.ToString()));
				bool cnb = String.IsNullOrEmpty (grd_jr_cont.CurrentRow.Cells [1].FormattedValue.ToString ());tracer.Trace(traceout, string.Format("\t\tcnb: {0}",cnb.ToString()));

				switch (colname) {
					case "Job Role":
						{
							switch (cnb) {
								case true:
									{
										grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value = ((ComboBox)sender).SelectedValue;
										grd_jr_cont.CurrentRow.Cells ["cbo_job_roles"].Value = grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value;
										jrid = (int)grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value;
										grd_jr_cont.CurrentRow.Cells ["str_id"].Value = contacts.Tables [programtype.ToString()].Rows [pi] ["str_id"];
										DataRow jrn = contacts.Tables ["job_roles"].Rows.Find (((ComboBox)sender).SelectedValue);
										grd_jr_cont.CurrentRow.Cells ["jr_name"].Value = jrn ["job_role"];tracer.Trace(traceout, string.Format("\t\t job role name: {0}",grd_jr_cont.CurrentRow.Cells["jr_name"].Value));
									}
									break;
								case false:
									{
										for (int i = 0; i < grd_jr_cont.Rows.Count - 2; i++) {
											if ((int)((ComboBox)sender).SelectedValue == (int)grd_jr_cont.Rows [i].Cells ["job_role_id"].Value &&
											    (int)grd_jr_cont.CurrentRow.Cells ["contact_id"].Value == (int)grd_jr_cont.Rows [i].Cells ["contact_id"].Value) {
												DataRow j = contacts.Tables ["job_roles"].Rows.Find (((ComboBox)sender).SelectedValue);
												string jn = j.ItemArray [1].ToString ();
												DataRow c = contacts.Tables ["contacts"].Rows.Find (grd_jr_cont.Rows [i].Cells ["contact_id"].Value);
												string cn = c ["full_name"].ToString ();
												MessageBox.Show (
													"A contact named " + cn +
													" has already been assigned to the job role " + jn + "!",
													"Assignment Already Exist",
													MessageBoxButtons.OK,
													MessageBoxIcon.Stop
												);
												((ComboBox)sender).ResetText ();
												grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value = "";
											}
										}
										grd_jr_cont.CurrentRow.Cells ["str_id"].Value = contacts.Tables [programtype.ToString()].Rows [pi] ["str_id"];
										grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value = ((ComboBox)sender).SelectedValue;
										cid = (int)grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
										grd_jr_cont.CurrentRow.Cells ["cbo_job_roles"].Value = grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value;
										jrid = (int)grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value;
										DataRow jrn = contacts.Tables ["job_roles"].Rows.Find (((ComboBox)sender).SelectedValue);
										grd_jr_cont.CurrentRow.Cells ["jr_name"].Value = jrn ["job_role"];
									}
									break;
							}
						}
						break;

					case "Full Name":
						{
							int csi = ((ComboBox)sender).SelectedIndex;

							switch (csi) {
								case -1:
									{ }
									break;
								case 0:
									{
										grd_jr_cont.CurrentRow.Cells ["contact_id"].Value = ((ComboBox)sender).SelectedValue;
										grd_jr_cont.CurrentRow.Cells [5].Value = "";
										grd_jr_cont.CurrentRow.Cells [6].Value = "";
										grd_jr_cont.CurrentRow.Cells [7].Value = "";
										grd_jr_cont.CurrentRow.Cells [8].Value = "";
										grd_jr_cont.CurrentRow.Cells [9].Value = "";
										grd_jr_cont.CurrentRow.Cells [10].Value = "";
										grd_jr_cont.CurrentRow.Cells [11].Value = "";
										grd_jr_cont.CurrentRow.Cells [12].Value = "";
										grd_jr_cont.CurrentRow.Cells [13].Value = "";
										grd_jr_cont.CurrentRow.Cells [14].Value = "";
										grd_jr_cont.CurrentRow.Cells [15].Value = "";
										grd_jr_cont.CurrentRow.Cells [16].Value = "";
										grd_jr_cont.CurrentRow.Cells [17].Value = "";
									}
									break;
								default:
									{
										switch (jrnb) {
											case true:
												{
													grd_jr_cont.CurrentRow.Cells ["str_id"].Value = contacts.Tables [programtype.ToString()].Rows [pi] ["str_id"];
													grd_jr_cont.CurrentRow.Cells ["contact_id"].Value = ((ComboBox)sender).SelectedValue;
													grd_jr_cont.CurrentRow.Cells ["cbo_contacts"].Value = grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
													cid = (int)grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
													DataRow conta = contacts.Tables ["contacts"].Rows.Find (((ComboBox)sender).SelectedValue);
													DataRow compa = contacts.Tables ["companies"].Rows.Find (conta.ItemArray [5]);
													DataRow cata = contacts.Tables ["categories"].Rows.Find (compa.ItemArray [9]);
													grd_jr_cont.CurrentRow.Cells [5].Value = conta.ItemArray [4];
													grd_jr_cont.CurrentRow.Cells [6].Value = compa.ItemArray [1];
													grd_jr_cont.CurrentRow.Cells [7].Value = compa.ItemArray [2];
													grd_jr_cont.CurrentRow.Cells [8].Value = compa.ItemArray [3];
													grd_jr_cont.CurrentRow.Cells [9].Value = compa.ItemArray [4];
													grd_jr_cont.CurrentRow.Cells [10].Value = compa.ItemArray [5];
													grd_jr_cont.CurrentRow.Cells [11].Value = compa.ItemArray [6];
													grd_jr_cont.CurrentRow.Cells [12].Value = conta.ItemArray [6];
													grd_jr_cont.CurrentRow.Cells [13].Value = compa.ItemArray [7];
													grd_jr_cont.CurrentRow.Cells [14].Value = compa.ItemArray [8];
													grd_jr_cont.CurrentRow.Cells [15].Value = conta.ItemArray [7];
													grd_jr_cont.CurrentRow.Cells [16].Value = conta.ItemArray [8];
													grd_jr_cont.CurrentRow.Cells [17].Value = cata.ItemArray [1];
												}
												break;
											case false:
												{
													
													for (int i = 0; i < grd_jr_cont.Rows.Count - 2; i++) {
														if ((int)((ComboBox)sender).SelectedValue == (int)grd_jr_cont.Rows [i].Cells ["contact_id"].Value &&
														    (int)grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value == (int)grd_jr_cont.Rows [i].Cells ["job_role_id"].Value) {
															DataRow c = contacts.Tables ["contacts"].Rows.Find (((ComboBox)sender).SelectedValue);
															string cn = c ["full_name"].ToString ();
															DataRow j = contacts.Tables ["job_roles"].Rows.Find (grd_jr_cont.Rows [i].Cells ["job_role_id"].Value);
															string jn = j.ItemArray [1].ToString ();
															MessageBox.Show (
																"A contact named " + cn +
																" has already been assigned to the job role " + jn + "!",
																"Assignment Already Exist",
																MessageBoxButtons.OK,
																MessageBoxIcon.Stop
															);
															((ComboBox)sender).ResetText ();
															grd_jr_cont.CurrentRow.Cells ["contact_id"].Value = "";
														}
													}
													grd_jr_cont.CurrentRow.Cells ["str_id"].Value = contacts.Tables [programtype.ToString()].Rows [pi] ["str_id"];
													grd_jr_cont.CurrentRow.Cells ["contact_id"].Value = ((ComboBox)sender).SelectedValue;
													jrid = (int)grd_jr_cont.CurrentRow.Cells ["job_role_id"].Value;
													grd_jr_cont.CurrentRow.Cells ["cbo_contacts"].Value = grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
													cid = (int)grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
													DataRow conta = contacts.Tables ["contacts"].Rows.Find (((ComboBox)sender).SelectedValue);
													DataRow compa = contacts.Tables ["companies"].Rows.Find (conta.ItemArray [5]);
													DataRow cata = contacts.Tables ["categories"].Rows.Find (compa.ItemArray [9]);
													grd_jr_cont.CurrentRow.Cells [5].Value = conta.ItemArray [4];
													grd_jr_cont.CurrentRow.Cells [6].Value = compa.ItemArray [1];
													grd_jr_cont.CurrentRow.Cells [7].Value = compa.ItemArray [2];
													grd_jr_cont.CurrentRow.Cells [8].Value = compa.ItemArray [3];
													grd_jr_cont.CurrentRow.Cells [9].Value = compa.ItemArray [4];
													grd_jr_cont.CurrentRow.Cells [10].Value = compa.ItemArray [5];
													grd_jr_cont.CurrentRow.Cells [11].Value = compa.ItemArray [6];
													grd_jr_cont.CurrentRow.Cells [12].Value = conta.ItemArray [6];
													grd_jr_cont.CurrentRow.Cells [13].Value = compa.ItemArray [7];
													grd_jr_cont.CurrentRow.Cells [14].Value = compa.ItemArray [8];
													grd_jr_cont.CurrentRow.Cells [15].Value = conta.ItemArray [7];
													grd_jr_cont.CurrentRow.Cells [16].Value = conta.ItemArray [8];
													grd_jr_cont.CurrentRow.Cells [17].Value = cata.ItemArray [1];
												}
												break;
										}
									}
									break;
							}
						}
						break;
				}
			} catch (System.Exception ex) {
				string subject = "combo_SelectionChangeCommitted error";
				ErrorHandling.ErrorEmail (subject, ex);
			}

			grd_jr_cont.CurrentRow.Cells ["timestamp"].Value = DateTime.Now;
			grd_jr_cont.CurrentRow.Cells ["user"].Value = Environment.UserName;
			_isdirty = contacts.HasChanges ();
			if (_isdirty) SaveButton.Enabled = true;
		}
		
		//this is the job role add button
		private void add_jr_Click (object sender, EventArgs e)
		{
			mess = new ContactMessage (grd_jr_cont);
			mess.Load += new EventHandler (mess_Load);
			mess.ShowDialog ();
		}

		//this is the contact add button
		private void add_cont_Click (object sender, EventArgs e)
		{
			contf = new ContactsAddEdit (
				contacts,
				contactsbs,
				"contacts",
				grd_jr_cont
			);
			contf.Load += new EventHandler (contf_Load);
			contf.ShowDialog ();tracer.Trace(traceout, "Showing Add Contact Dialog box");

			contf.FormClosed += new FormClosedEventHandler (contf_FormClosed);
			contf.FormClosing += new FormClosingEventHandler (contf_FormClosing);
		}

		//this is the contact edit button"
		private void edit_cont_Click (object sender, EventArgs e)
		{
			try {
				int cr = grd_jr_cont.CurrentRow.Index;
				grd_jr_cont.CurrentCell = grd_jr_cont.Rows [cr].Cells [1];
				object cid = grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
				//DataRow position = contacts.Tables["contacts"].Rows.Find(cid);
				Position = (int)cid;
				contf = new ContactsAddEdit (
					contacts,
					contactsbs,
					Position,
					"contacts",
					grd_jr_cont,
					TimeofPull,
					contf
				);
				//ContactsAddEdit cf = new ContactsAddEdit(contacts, contactsbs, (int)grd_jr_cont.CurrentCell.Value, "contacts", grd_jr_cont);

				contf.Load += new EventHandler (contf_Load);
				contf.ShowDialog ();

				contf.FormClosed += new FormClosedEventHandler (contf_FormClosed);
				contf.FormClosing += new FormClosingEventHandler (contf_FormClosing);
			} catch {
				MessageBox.Show (
					"You must select a row that contains a contact to enable edit.",
					"Edit Form Message",
					MessageBoxButtons.OK
				);
			}
		}

		//a double click on a contact opens the contact edit form

		private void grd_jr_cont_CellMouseDoubleClick (object sender, DataGridViewCellMouseEventArgs e)
		{
			edit_cont_Click (sender, e);
		}

		private void grd_jr_cont_CancelRowEdit (object sender, QuestionEventArgs e)
		{

			if (rowinEdit == grd_jr_cont.Rows.Count - 2 && rowinEdit == contacts.Tables ["project_contacts"].Rows.Count) {

			}
		}

		private void grd_jr_cont_RaiseCellContentClick (object sender, DataGridViewCellEventArgs e)
		{
			int ci = grd_jr_cont.CurrentCell.ColumnIndex;
			if (ci == 16) {
				#if!__MonoCS__
				Outlook.Application ol = (Outlook.Application)System.Runtime.InteropServices.Marshal.GetActiveObject ("Outlook.Application");
				Outlook._MailItem olm = (Outlook._MailItem)ol.CreateItem (Outlook.OlItemType.olMailItem);
				string email = (string)grd_jr_cont.CurrentCell.Value;
				olm.To = email;
				olm.Display ();
				#endif
			}
		}
		
		private void dgv_KeyDown (object sender, KeyEventArgs e)
		{
			try {
				//this handles deleting rows on the datagridview.  A save is not required...this updates mysql automatically
				tracer.Trace(traceout, "Deleting Row");
				if (e.KeyCode == Keys.Delete) {
					view = (DataView)((DataGridView)sender).DataSource;
					int rc = view.ToTable ().Rows.Count;
					string table = view.Table.TableName;tracer.Trace(traceout, string.Format("\tFrom Table: {0}",table));
					
					if (table == "project_contacts") {
						SaveButton.Enabled = false;
						pb2.Visible = true;
						pb2.Maximum = rc * 4;
						pb2.Minimum = 0;
						pb2.Step = 1;
						lab_save.Visible = true;
						pb2.Value = 1;
						pb2.PerformStep ();
						pb2.Refresh ();
						lab_save.Text = "Delete starting...";
						lab_save.Refresh ();
						pcid = (int)grd_jr_cont.CurrentRow.Cells ["project_contact_id"].Value;
						pc = contacts.Tables ["project_contacts"].Rows.Find (pcid);tracer.Trace(traceout, string.Format("\t\tFinding project_contacts contact id: {0}",pcid));
						pc.Delete ();
						connect.Connect ("contacts");tracer.Trace(traceout, "Connecting to MySql Server");
						connect.DeleteProjectContacts (
							grd_jr_cont,
							pcid,
							pi,
							ProjectTypes.GroundUp,
							pb2,
							lab_save
						);
						connect.Disconnect ();tracer.Trace(traceout, "Disconnect from MySql Server");
						view = new DataView (contacts.Tables ["project_contacts"]);
						view.RowFilter = string.Format (
							"str_id = {0}",
							cbo_projects.SelectedValue
						);
						view.Sort = "jr_name, full_name";
						grd_jr_cont.DataSource = view;
						func.FillRows (contacts, grd_jr_cont, pb2, lab_save);
						//SaveButton.Enabled = true;
						pb2.Visible = false;
						lab_save.Visible = false;
						MessageBox.Show (
							"Delete was successful!",
							"Delete Confirmed"
						);
					} else if (((DataView)sender).Table.TableName == "project_contacts_remodels") {

					}
				} else if (e.KeyCode == Keys.Enter) {
					
				}
				
			} catch (System.Exception ex) {
				string subject = "dgv_KeyDown error";
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}

		private void Contacts_UserAddedRow(object sender, DataGridViewRowEventArgs e)
    {
		  _isdirty = true;
      SaveButton.Enabled = true;
    }
		
		//this currently is non-functioning...
		void backgw_ProgressChanged (object sender, ProgressChangedEventArgs e)
		{
			pb2.Value = e.ProgressPercentage;
			pb2.PerformStep ();
			lab_save.Text = e.UserState.ToString ();
		}

		//this currently is non-functioning...
		void worker_RunWorkerCompleted (object sender, RunWorkerCompletedEventArgs e)
		{
			
			
		}

		//this currently is non-functioning...
		void worker_DoWork (object sender, DoWorkEventArgs e)
		{
			worker = sender as BackgroundWorker;
			worker.WorkerReportsProgress = true;
			
		}

		void mess_Load (object sender, EventArgs e)
		{
			// remove the event handler here so the garbage collection
			// can clean up the object when the form is closed.
			// Don't worry new events get hooked when combobox index changes.
			mess.Load -= new EventHandler (mess_Load);
		}

		private void editform (object sender)
		{
			bool nri = (grd_jr_cont.CurrentCell.RowIndex == grd_jr_cont.NewRowIndex);
			int ci = grd_jr_cont.CurrentCell.ColumnIndex;
			cr = grd_jr_cont.CurrentRow;

			switch (ci) {
				case 0:
					{
						mess = new ContactMessage (grd_jr_cont);
						mess.Load += new EventHandler (mess_Load);
						mess.ShowDialog ();
					}
					break;

				case 1:
					{
						try {
							object cid = grd_jr_cont.CurrentRow.Cells ["contact_id"].Value;
							//DataRow position = contacts.Tables["contacts"].Rows.Find(cid);
							Position = (int)cid;
							contf = new ContactsAddEdit (
								contacts,
								contactsbs,
								Position,
								"contacts",
								grd_jr_cont,
								TimeofPull,
								contf
							);
							ContactsAddEdit cf = new ContactsAddEdit (
								contacts,
								contactsbs,
								(int)grd_jr_cont.CurrentCell.Value,
								"contacts",
								grd_jr_cont,
								TimeofPull,
								contf
							);

							contf.Load += new EventHandler (contf_Load);
							contf.ShowDialog ();

							contf.FormClosed += new FormClosedEventHandler (contf_FormClosed);
							contf.FormClosing += new FormClosingEventHandler (contf_FormClosing);
						} catch (InvalidCastException ex) {
							string subject = "editform error";
							ErrorHandling.ErrorEmail (subject, ex);
						}
					}
					break;
			}
		}

		private void grd_jr_cont_CurrentCellDirtyStateChanged (object sender, EventArgs e)
		{
			if (grd_jr_cont.IsCurrentCellDirty) {
				grd_jr_cont.CommitEdit (DataGridViewDataErrorContexts.Commit);
				grd_jr_cont.EndEdit (DataGridViewDataErrorContexts.Commit);
			}
		}

		void contf_FormClosing (object sender, FormClosingEventArgs e)
		{tracer.Trace(traceout, string.Format("Closing Add Contact Dialog"));
			func.FillRows (contacts, grd_jr_cont, pb2, lab_save);tracer.Trace(traceout, string.Format("Filling rows"));
		}

		void contf_FormClosed (object sender, FormClosedEventArgs e)
		{
			Form temp = (Form)sender;
			temp.Dispose ();
		}

		void contf_Load (object sender, EventArgs e)
		{
		}
		
		public void compe_FormClosing (object sender, FormClosingEventArgs e)
		{
			func.FillRows (contacts, grd_jr_cont, pb2, lab_save);
		}

		public void compe_FormClosed (object sender, FormClosedEventArgs e)
		{
		}

		private void grd_jr_cont_DataError (object sender, DataGridViewDataErrorEventArgs anError)
		{
			//mailman.sendmail("Contacts Grid View Error", anError.Context.ToString());
			//MessageBox.Show("Error happened " + anError.Context.ToString());

			if (anError.Context == DataGridViewDataErrorContexts.Commit) {
				int ci = grd_jr_cont.CurrentCell.ColumnIndex;
				int nri = grd_jr_cont.NewRowIndex;
				switch (ci) {
					case 0:
						{
							if (grd_jr_cont.CurrentCell.RowIndex == nri) {
								int csv = (int)grd_jr_cont.CurrentCell.Value;
								DataRow namerow = contacts.Tables ["job_roles"].Rows.Find (csv);
								string name = (string)namerow.ItemArray [1];
								if (grd_jr_cont.CurrentCell.ColumnIndex == 0 && name == "<new job role required>") {
									grd_jr_cont.CommitEdit (DataGridViewDataErrorContexts.Commit);
									grd_jr_cont.EndEdit (DataGridViewDataErrorContexts.Commit);
								}
							}
						}
						break;
					case 1:
						{
							if (grd_jr_cont.CurrentCell.RowIndex == nri) {
								int csv = (int)grd_jr_cont.CurrentCell.Value;
								DataRow namerow = contacts.Tables ["contacts"].Rows.Find (csv);
								string name = (string)namerow.ItemArray [9];
								if (grd_jr_cont.CurrentCell.ColumnIndex == 1 && name == "<new contact required>") {
									grd_jr_cont.CommitEdit (DataGridViewDataErrorContexts.Commit);
									grd_jr_cont.EndEdit (DataGridViewDataErrorContexts.Commit);
									grd_jr_cont.CurrentCell = grd_jr_cont.CurrentRow.Cells [ci + 1];
									grd_jr_cont.CurrentCell = grd_jr_cont.CurrentRow.Cells [ci];
								}
							}
						}
						break;
				}
			}

			if (anError.Context == DataGridViewDataErrorContexts.CurrentCellChange) {
				MessageBox.Show ("Cell change");
			}
			if (anError.Context == DataGridViewDataErrorContexts.Parsing) {
				MessageBox.Show ("parsing error");
			}
			if (anError.Context == DataGridViewDataErrorContexts.LeaveControl) {
				MessageBox.Show ("leave control error");
			}
			if (anError.Context == DataGridViewDataErrorContexts.PreferredSize) {
				anError.Cancel = true;
			}

			if ((anError.Exception) is ConstraintException) {
				DataGridView view = (DataGridView)sender;
				view.Rows [anError.RowIndex].ErrorText = "an error";
				view.Rows [anError.RowIndex].Cells [anError.ColumnIndex].ErrorText = "an error";

				anError.ThrowException = false;
			}
		}

		/// <summary>
		/// Event fires when "options" is clicked under the prefereces menu
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void optionsToolStripMenuItem_Click (object sender, EventArgs e)
		{
			OpForm o = new OpForm ();
			o.StartPosition = FormStartPosition.CenterParent;
			o.ShowDialog ();
			o.FormClosed += new FormClosedEventHandler (OptionFormClosed);
		}

		private void OptionFormClosed (object sender, EventArgs e)
		{
			FormatStoreNames ();
			FormatSelectorNames ();
		}
		

		/// <summary>
		/// Event fires when "Feature Request" is click under the  preferences menu
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void featureRequestToolStripMenuItem_Click (object sender, EventArgs e)
		{
			FeatureRequest f = new FeatureRequest ();
			f.StartPosition = FormStartPosition.CenterParent;
			f.ShowDialog ();
		}

		//this is the save button for the datagridview
		public void SaveButton_Click (object sender, EventArgs e)
		{
			try {tracer.Trace(traceout, "Saving Data to Mysql");
				//OutlookConn conn = new OutlookConn(grd_jr_cont, contacts);
				a = contacts.HasChanges (DataRowState.Added);
				d = contacts.HasChanges (DataRowState.Deleted);
				m = contacts.HasChanges (DataRowState.Modified);
				if (a == false && d == false && m == false) {
					MessageBox.Show (
						"There are no changes to save.",
						"No Changes To Save",
						MessageBoxButtons.OK
					);tracer.Trace(traceout, "Found no changes **TODO: Disable save button until it is needed**");
					return;
				}

				int rc = grd_jr_cont.Rows.Count;
				connect.Connect ("contacts");tracer.Trace(traceout, "Connecting to Mysql Server");
				connect.LoadProjectContactsComp (ref currentpc);
				int nr = grd_jr_cont.NewRowIndex;
				int strid = (int)cbo_projects.SelectedValue;
				//DataRow[] verify = currentpc.Select(string.Format("str_id = '{0}'",
				//    strid));

				SaveButton.Enabled = false;
				pb2.Visible = true;
				pb2.Maximum = rc * 4;
				pb2.Minimum = 0;
				pb2.Step = 1;
				lab_save.Visible = true;
				pb2.Value = 1;
				pb2.PerformStep ();
				pb2.Refresh ();
				lab_save.Text = "Add/Edit store contacts starting...";tracer.Trace(traceout, lab_save.Text);
				lab_save.Refresh ();

				for (int c = 0; c < grd_jr_cont.Rows.Count - 1; c++) {
					pb2.PerformStep ();
					pb2.Refresh ();
					lab_save.Text = "Reconstructing this view...";
					lab_save.Refresh ();
					int pci = (int)grd_jr_cont ["project_contact_id", c].Value;
					DataRow prjcont = contacts.Tables ["project_contacts"].Rows.Find (pci);
					int jrio = (int)prjcont ["job_role_id"];
					int cio = (int)prjcont ["contact_id"];
					DataRow proj = contacts.Tables [programtype.ToString()].Rows.Find (strid);
					string project = proj ["str_sel"].ToString ();
					int jri = (int)grd_jr_cont ["job_role_id", c].Value;
					string jrn = (string)grd_jr_cont [0, c].FormattedValue;
					int ci = (int)grd_jr_cont ["contact_id", c].Value;
					string cnt = (string)grd_jr_cont [1, c].FormattedValue;
					DataRow[] verify = currentpc.Select (string.Format (
						"str_id = '{0}' AND job_role_id = '{1}' AND contact_id = '{2}'",
						strid,
						jri,
						ci
					)
					                                    );
					if (verify.Length != 0) {
						int pcv = (int)verify [0] ["project_contact_id"];
						if (pci != pcv) {
							var result = MessageBox.Show ("Since you logged on a record has been created that matches your entry!\n\nYour entry of " + cnt + " assigned to " +
							                              jrn + " has a project contact ID of " + pci + ".\n\nCurrent record of " + cnt + " assigned to " + jrn +
							                              " has a project contact ID of " + pcv + ".\n\n" +
							                              "The row will be reset back to it's original value.\n\nIf indeed the records need to be deleted do so on return to the project contact screen",
							                              "Duplicate Record", MessageBoxButtons.OK,
							                              MessageBoxIcon.Stop);
							grd_jr_cont ["job_role_id", c].Value = jrio;
							grd_jr_cont ["contact_id", c].Value = cio;
						}
					}
				}
				
				MySqlConn con = new MySqlConn (
					contacts,
					contacts.Tables ["project_contacts"]
				);tracer.Trace(traceout, "\tnew Mysql Connection class");
				con.StatmentCompleted += new MySqlConn.SaveStatementComplete (con_StatmentCompleted);
				connect.StatmentCompleted += new MySqlConn.SaveStatementComplete (con_StatmentCompleted);
				connect.MysqlPreSave (
					contacts,
					contacts.Tables ["project_contacts"],
					grd_jr_cont,
					original,
					current,
					id,
					TimeofPull
				);tracer.Trace(traceout, "\tMysql Save Complete");
				func.FillFolder (
					contacts,
					grd_jr_cont,
					pi,
					ProjectType,
					pb2,
					lab_save
				);tracer.Trace(traceout, "\tFill Folder Complete");
				func.FillSpreadsheet (
					contacts,
					grd_jr_cont,
					pi,
					ProjectType,
					pb2,
					lab_save
				);tracer.Trace(traceout, "\tFill SpreadSheet complete");
				pb2.Value = pb2.Maximum;
				//SaveButton.Enabled = true;
				pb2.Visible = false;
				lab_save.Visible = false;
				MessageBox.Show ("Save was successful!", "Save Confirmed");
			} catch (System.Exception ex) {
				string subject = "SaveButton_Click (selectform) error";
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}

		private void but_email_Click (object sender, EventArgs e)
		{
			try {

				StringBuilder sbto = new StringBuilder ();
				StringBuilder sbcc = new StringBuilder ();
				StringBuilder sbbc = new StringBuilder ();
				StringBuilder subj = new StringBuilder ();

				for (int i = 0; i < grd_jr_cont.Rows.Count - 1; i++) {
					DataGridViewRow row = grd_jr_cont.Rows [i];

					for (int c = 2; c < 5; c++) {
						DataGridViewCell cell = grd_jr_cont.Rows [i].Cells [c];
						string name = cell.OwningColumn.Name;

						if ((bool)row.Cells [name].EditedFormattedValue == true) {
							DataGridViewLinkCell lc = (DataGridViewLinkCell)row.Cells ["tbo_email"];
							string email = lc.EditedFormattedValue.ToString ();

							switch (name) {
								case "to":
									{
										int sbl = sbto.Length;
										if (sbl == 0) {
											sbto.Insert (0, email);
										} else {
											sbto.Append ("; " + email);
										}
									}
									break;
								case "cc":
									{
										int sbl = sbcc.Length;
										if (sbl == 0) {
											sbcc.Insert (0, email);
										} else {
											sbcc.Append ("; " + email);
										}
									}
									break;
								case "bc":
									{
										int sbl = sbbc.Length;
										if (sbl == 0) {
											sbbc.Insert (0, email);
										} else {
											sbbc.Append ("; " + email);
										}
									}
									break;
							}
						}
					}
				}

				tostr = sbto.ToString ();
				ccstr = sbcc.ToString ();
				bcstr = sbbc.ToString ();
				#if!__MonoCS__
				Outlook.Application ol = (Outlook.Application)System.Runtime.InteropServices.Marshal.GetActiveObject ("Outlook.Application");
				Outlook._MailItem olm = (Outlook._MailItem)ol.CreateItem (Outlook.OlItemType.olMailItem);
				olm.To = tostr;
				olm.CC = ccstr;
				olm.BCC = bcstr;
				#endif
				subj.Insert (0, tbo_str_num.Text);
				subj.Append ("-" + tbo_str_seq.Text + " " + tbo_str_city.Text + ", " + tbo_str_st.Text + " -");
				#if!__MonoCS__
				olm.Subject = subj.ToString ();
				olm.Display ();
				#endif
			} catch (System.Exception ex) {
				string subject = "but_email_Click error";
				ErrorHandling.ErrorEmail (subject, ex);
			}
		}

		void con_StatmentCompleted (string SqlStatement)
		{tracer.Trace(traceout, "\tempty mysql statement completed event");
		}

		public AutoCompleteMode AutoCompleteMode { get; set; }

		private void tbo_time_TextChanged(object sender, EventArgs e)
		{

		}
		
		void ContactsLayout(object sender, LayoutEventArgs e)
		{
			this.Activate();
		}
		
		void ContactsSizeChanged(object sender, EventArgs e)
		{tracer.Trace(traceout, "Contacts Form Size Changed");
		  Settings.Default.FORM_SIZE = this.ClientSize;tracer.Trace(traceout, string.Format("\tNew Form Size: {0}", Settings.Default.FORM_SIZE));
			Settings.Default.Save();
		}

        private void tbo_str_num_TextChanged(object sender, EventArgs e)
        {

        }

        private void lab_str_seq_Click(object sender, EventArgs e)
        {

        }

        private void tbo_str_seq_TextChanged(object sender, EventArgs e)
        {

        }
	}
}